package de.cdtm.whackathon.bloodwine.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.cobogw.gwt.waveapi.gadget.client.Participant;

import com.google.gwt.dev.Link;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class BloodwinePanel extends Panel {
	private final BloodwineState state;
	private final OptionPanel optionPanel;
	private final ResultPanel resultPanel;
	
	public BloodwinePanel(Bloodwine waveGadget) {
		this.state = new BloodwineState(waveGadget.getWave());
		
		VerticalPanel panel = new VerticalPanel();
		RootPanel.get().add(panel);
		
		Map<Participant, Set<String>> result = new HashMap<Participant, Set<String>>();
		
		optionPanel = new OptionPanel();
		panel.add(optionPanel);
		
		panel.add(new AddPanel());
		
		resultPanel = new ResultPanel(result);
		panel.add(resultPanel);
	}
	
	private Map<String, Integer> getResult() {
		Map<String, Set<String>> choices = state.getChoices();
		List<String> options = new ArrayList<String>(state.getOptions());
		Collections.sort(options);
		Map<String, Integer> result = new HashMap<String, Integer>();
		
		for(String option : options)
			result.put(option, 0);
		
		for(String participant : choices.keySet()) {
			Set<String> participantChoices = choices.get(participant);
			for(String option : participantChoices) {
				result.put(option, result.get(option)+1);
			}
		}
		
		return result;
	}
	
	private class OptionPanel extends VerticalPanel {
		public void update() {
			clear();
			
			List<String> options = new ArrayList<String>(state.getOptions());
			Collections.sort(options);
			Set<String> ownOptions = state.getOwnChoices();
			Map<String, Integer> result = getResult();
						
			for(int i=0; i<options.size(); i++) {
				final String option = options.get(i);
				
				final HorizontalPanel optionPanel = new HorizontalPanel();
				optionPanel.setSpacing(5);

				final CheckBox checkBox = new CheckBox(option);
				checkBox.addClickHandler(new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						state.setChoice(option, checkBox.getValue());
					}
				});
				checkBox.setValue(ownOptions.contains(option));
				
				optionPanel.add(checkBox);
				optionPanel.add(new Label("("+result.get(option)+")"));
				optionPanel.add(new Button("remove", new ClickHandler() {
					public void onClick(ClickEvent event) {
						state.removeOption(option);
					}
				}));
				
				add(optionPanel);
			}
		}
	}
	
	private class AddPanel extends HorizontalPanel {
		private final TextBox textBox;
		private final Button addButton;

		public AddPanel() {
			textBox = new TextBox();
			addButton = new Button("Add Option");
			
			addButton.addClickHandler(new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					try {
						state.addOption(textBox.getValue());
					}
					catch(IllegalArgumentException e) {
						Window.alert(e.getMessage());
					}
				}
			});
			
			add(textBox);
			add(addButton);
		}
	}
	
	private class ResultPanel extends VerticalPanel {
		public ResultPanel(Map<Participant, Set<String>> result) {
			update();
		}
		
		public void update() {
			clear();

			Map<String, Set<String>> result = state.getChoices();
			
			for(String participantId : result.keySet()) {
				final Participant participant = state.getParticipantById(participantId);
				HorizontalPanel participantResult = new HorizontalPanel();
				
				Image thumbnail = new Image(participant.getThumbnailUrl());
				thumbnail.setHeight("30");
				thumbnail.setWidth("30");
				participantResult.add(thumbnail);
				
				StringBuilder str = new StringBuilder();
				str.append(participant.getDisplayName());
				str.append(": ");
				for(String choice : result.get(participantId)) {
					str.append(choice);
					str.append(", ");
				}
				str.setLength(str.length()-2);
				participantResult.add(new Label(str.toString()));
				add(participantResult);
			}
		}
	}
	
	public void updateResult() {
		resultPanel.update();
		optionPanel.update();
	}
	
	@Override
	public boolean remove(Widget arg0) {
		return false;
	}

	@Override
	public Iterator<Widget> iterator() {
		return null;
	}
}
